<template>
  <div style="width: 100%; height: 100%"  :style="{ isSelected: 'outline: 2px solid red' }">
    <Table ref="fTable" v-if="show" style="width: 100%; height: 100%;border-collapse: collapse;">
        <caption v-if="tableConfig.caption">{{ tableConfig.caption }}</caption>
        <thead>
            <tr v-for="rowIndex in tableConfig.getHeaderRowArray()" :key="rowIndex + '_tr'">
                <template  v-for="columnIndex in tableConfig.getColumnArray()">
                    <th v-if="!tableConfig.spanHideHeadersCells.has(rowIndex + '___' + columnIndex)" :key="columnIndex + '_th'" :colspan="tableConfig.getHeaderCellSpan(rowIndex, columnIndex)[0]" :rowspan="tableConfig.getHeaderCellSpan(rowIndex, columnIndex)[1]"> 
                        {{ tableConfig.headers[rowIndex] ? (tableConfig.headers[rowIndex][columnIndex] ? tableConfig.headers[rowIndex][columnIndex].value : '') : "" }}
                    </th>
                </template>
            </tr>
        </thead>

        <tr v-for="rowIndex in tableConfig.getRowArray()" :key="rowIndex">
            <template v-for="columnIndex in tableConfig.getColumnArray()" >
                <TableCell
                v-if="!tableConfig.spanHideCells.has(rowIndex + '___' + columnIndex)"
                :key="columnIndex + 's'"
                :colspan="tableConfig.getCellSpan(rowIndex, columnIndex)[0]"
                :rowspan="tableConfig.getCellSpan(rowIndex, columnIndex)[1]"
                :style = "getCellStyle(rowIndex, columnIndex)"
                :defData="tableConfig.getCell(rowIndex, columnIndex)" :rowIndex="rowIndex" :columnIndex="columnIndex" @cell-click="cellClicked" :readonly="readonly"></TableCell>
            </template>
        </tr>
    </Table>
  </div>
</template>
<script>
import TableCell from './TableCell.vue';
export default {
    components: {
        TableCell
    },
    props: {
        cells: {
            type: Object,
            default: () => ({})
        },
        headers: {
            type: Object,
            default: () => ({})
        },
        rowCount: {
            type: Number,
            default: null
        },
        columnCount: {
            type: Number,
            default: null
        },
        readonly:{
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            show: true,
            curCell: null,
            tableConfig: {
                headers: this.headers,
                cells: this.cells,
                rowCount: this.rowCount,
                columnCount: this.columnCount,
                spanHideCells: new Set(),
                spanHideHeadersCells: new Set(),
                clear() {
                    this.spanHideCells.clear();
                    this.spanHideHeadersCells.clear();
                },
                getHeaderRowArray() {
                    return Array(Math.max(...Object.keys(this.headers).map(t => parseInt(t))) + 1).fill().map((_, index) => index);
                },
                getRowArray() {
                    if (this.rowCount != null) {
                        return Array(this.rowCount).fill().map((_, index) => index);
                    } else {
                        return Array(Math.max(...Object.keys(this.cells).map(t => parseInt(t))) + 1).fill().map((_, index) => index);
                    }
                },
                getColumnArray() {
                    if (this.columnCount != null) {
                        return Array(this.columnCount).fill().map((_, index) => index);
                    } else {
                        if (this.__maxColumnIndex == undefined || this.__maxColumnIndex == null) {
                            let rows = Object.keys(this.cells);
                            let maxColumnIndex = -1;
                            for (let row of rows) {
                                let columns = Object.keys(this.cells[row]);
                                maxColumnIndex = Math.max(maxColumnIndex, ...columns.map(t => parseInt(t)))
                            }
                            this.__maxColumnIndex = maxColumnIndex;
                        }
                        return Array(this.__maxColumnIndex + 1).fill().map((_, index) => index);
                    }

                },
                getCell(rowIndex, columnIndex) {
                    if (this.cells[rowIndex] && this.cells[rowIndex][columnIndex]) {
                        return this.cells[rowIndex][columnIndex];
                    } else {
                        return null;
                    }
                },
                getCellValue(rowIndex, columnIndex) {
                    let cell = this.getCell(rowIndex, columnIndex);
                    if (cell) {
                        return cell.value;
                    } else {
                        return undefined;
                    }
                },
                getCellSpan(rowIndex, columnIndex) {
                    if (this.cells[rowIndex] && this.cells[rowIndex][columnIndex]) {
                        let colspan = (() => {
                            if (this.cells[rowIndex][columnIndex].colspan) {
                                return this.cells[rowIndex][columnIndex].colspan;
                            } else {
                                return 1;
                            }
                        })();
                        let rowspan = (() => {
                            if (this.cells[rowIndex][columnIndex].rowspan) {
                                return this.cells[rowIndex][columnIndex].rowspan;
                            } else {
                                return 1;
                            }
                        })();
                        for (let i = 0; i < rowspan; i++) {
                            for (let j = 0; j < colspan; j++) {
                                if (i != 0 || j != 0) {
                                    this.spanHideCells.add(`${rowIndex + i}___${columnIndex + j}`);
                                }
                            }
                        }
                        return [colspan, rowspan];
                    } else {
                        return [1, 1];
                    }
                },
                getHeaderCellSpan(rowIndex, columnIndex) {
                    if (this.headers[rowIndex] && this.headers[rowIndex][columnIndex]) {
                        let colspan = (() => {
                            if (this.headers[rowIndex][columnIndex].colspan) {
                                return this.headers[rowIndex][columnIndex].colspan;
                            } else {
                                return 1;
                            }
                        })();
                        let rowspan = (() => {
                            if (this.headers[rowIndex][columnIndex].rowspan) {
                                return this.headers[rowIndex][columnIndex].rowspan;
                            } else {
                                return 1;
                            }
                        })();
                        for (let i = 0; i < rowspan; i++) {
                            for (let j = 0; j < colspan; j++) {
                                if (i != 0 || j != 0) {
                                    this.spanHideHeadersCells.add(`${rowIndex + i}___${columnIndex + j}`);
                                }
                            }
                        }
                        return [colspan, rowspan];
                    } else {
                        return [1, 1];
                    }
                },
            }
        }
    },
    mounted() {
        window.fTable = this.$refs.fTable;
        window.tableConfig = this.tableConfig;
    },
    methods: {
        cellClicked(cell) {
            if (this.curCell) {
                this.curCell.isSelected = false;
            }
            this.curCell = cell;
        },
        //在指定位置插入一行，其余行下移
        insertRowAt(index, rowDef) {
            this.show = false
            this.tableConfig.rowCount++;
            this.tableConfig.clear();
            for (let i = this.tableConfig.rowCount - 1; i >= index; i--) {
                this.tableConfig.cells[i + 1 + ''] = this.tableConfig.cells[i + '']
            }
            this.tableConfig.cells[index + ''] = rowDef;
            this.curCell.isSelected = true;
            this.$nextTick(() => {
                this.show = true;
            })            
        },
        //在指定位置删除一行，后面行上移
        deleteRowAt(index) {
            this.show = false
            this.tableConfig.clear();
            for (let i = index ; i < this.tableConfig.rowCount - 1; i++) {
                this.tableConfig.cells[i+''] = this.tableConfig.cells[i + 1 + '']
            }            
            this.tableConfig.rowCount--;
            this.curCell.isSelected = true;
            this.$nextTick(() => {
                this.show = true;
            })            
        },
        //获得单元格的值
        getCellValue(rowIndex, columnIndex) {
            return this.tableConfig.getCellValue(rowIndex, columnIndex);
        },
        getCellStyle(rowIndex, columnIndex) {
            let cell = this.tableConfig.getCell(rowIndex, columnIndex);
            if(cell && cell.style){
                let style= ""
                Object.keys(cell.style)
                .forEach(key => {
                        style+= `${key}:${cell.style[key]};`
                    }
                )
                return style;
            }else{
                return "";
            }
        },
        getPositionByValue(value) {
            for (let r in this.cells) {
                for (let c in this.cells[r]) {
                    if (this.cells[r][c] == value) {
                        return { row: r, column: c }
                    }
                }
            }
            return null;
        },
        setCellValue(rowIndex, columnIndex, value) {
            if (this.tableConfig.getCell(rowIndex, columnIndex)) {
                this.tableConfig.getCell(rowIndex, columnIndex).value = value;
            }
        },
    }
}
</script>
<style scoped>
caption {
    padding: 0 0 5px 0;
    width: 700px;
    text-align: right;
}

table {
    outline: #9eb6ce 1px solid;
}

th {
    color: black;
    border: 1px solid #bfd7d4;
    letter-spacing: 2px;
    text-transform: uppercase;
    text-align: center;
    background: #e9eff6 no-repeat;
    height: 27px;
    line-height: 27px;
}

thead {
    position: relative;
}

thead::after {
    content: "";
    position: absolute;
    box-sizing: border-box;
    left: 0px;
    right: -1px;
    top: -1px;
    bottom: 0px;
    z-index: 10;
    display: block;
    border-bottom: #9eb6ce 1px solid;
}

th.nobg {
    border-top: 0;
    border-left: 0;
    border-right: 1px solid #C1DAD7;
    background: none;
}

td {
    border: 1px solid #C1DAD7;
    background: #fff;
    font-size: 11px;
    padding: 6px 6px 6px 12px;
    color: #000000;
    height: 27px;
    padding: 0px;
    min-width: 50px;
    text-align: center;
}

td.alt {
    background: #F5FAFA;
    color: #797268;
}

th.spec {
    border-left: 1px solid #C1DAD7;
    border-top: 0;
    background: #fff no-repeat;
}

th.specalt {
    border-left: 1px solid #C1DAD7;
    border-top: 0;
    background: #f5fafa no-repeat;
    color: #797268;
}

/*———for IE 5.x bug*/
html>body td {
    font-size: 11px;
}

body,
td,
th {
    font-family: 宋体, Arial;
    font-size: 12px;
}
select:disabled {
  color: #000000;
}
</style>